//////////////////////////////////////////////////////////////////////////////////
//	Copyright 2011 by Yosef Grabivker, ryuho@homenetworksoft.com
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//////////////////////////////////////////////////////////////////////////////////

#include <wx/wx.h>
#include <sstream>
#include "propertystorage.h"
#include "configdata.h"
#include "sysdepapi.h"
#include "guilogic.h"

#define XML_ROOT_EL_NAME 						"properties"
#define XML_EL_ID 	 							"property"
#define XML_ATTR_ID 							"id"
#define XML_ATTR_WRN_LEVEL						"w_lvl"
#define XML_ATTR_ALR_LEVEL						"a_lvl"
#define XML_ATTR_WRN_STRAT						"w_strat"
#define XML_ATTR_ALR_STRAT						"a_strat"
#define XML_ATTR_WRN_SCRIPT						"w_script"
#define XML_ATTR_ALR_SCRIPT						"a_script"
#define XML_ATTR_REPAIR							"repair"

#define XML_SYSLOG_EL_ID 						"action"
#define XML_ATTR_SLOG_ID						"id"
#define XML_ATTR_SLOG_PATT						"pattern"
#define XML_ATTR_SLOG_ACT						"act"
#define XML_ATTR_SLOG_RUN						"run"

#define XML_ATTR_ENABLE_NAT_OPT					"e_nat_opt"
#define XML_ATTR_ENABLE_NAT_SZ_OPT				"e_nat_sz_opt"
#define XML_ATTR_ENABLE_P2P_OPT					"e_p2p_opt"
#define XML_ATTR_ENABLE_WWW_OPT					"e_www_opt"
#define XML_ATTR_ENABLE_TCP_OPT					"e_tcp_opt"
#define XML_ATTR_ENABLE_ICMP_OPT				"e_icmp_opt"
#define XML_ATTR_ENABLE_ADVANCED_OPT			"e_advanced_opt"
#define XML_ATTR_ENABLE_STUP_SC					"e_startup_script_opt"
#define XML_ATTR_ENABLE_STUP_SC_FN				"e_startup_script_file"
#define XML_ATTR_ENABLE_MOD_UNLOAD				"e_mod_unload"
#define XML_ATTR_ENABLE_PROC_KILL				"e_proc_kill"

#define PROC_LIST_ID							"proc_list"
#define MOD_LIST_ID								"mod_list"
#define DELIM_STR_LIST							'#'

//Syslog
#define XML_ATTR_SYSLOG_FROMRONLY_OPT			"sl_rt_only_opt"
#define XML_ATTR_SYSLOG_LOGMACBLOCK_OPT			"sl_log_mac_blocks"
#define XML_ATTR_SYSLOG_ENABLEAUTOSAVE_OPT		"sl_log_enable_autosave"
#define XML_ATTR_SYSLOG_FILE_OPT				"sl_log_file"
#define XML_ATTR_SYSLOG_FILE_OPT_2				"sl_log_dir"
#define XML_ATTR_SYSLOG_UDP_PORT				"sl_udp_port"
#define XML_ATTR_SYSLOG_FILELIMIT_OPT			"sl_log_file_limit"
#define XML_ATTR_SYSLOG_AUTO_CONF				"sl_log_autoconf"
#define XML_ATTR_SYSLOG_AUTO_CONF_LVL			"sl_log_autoconf_lvl"

#define XML_VAL_TRUE							"true"
#define XML_VAL_FALSE							"false"

//Filters
#define XML_FILTER_ROOT_EL_NAME					"filters"
#define XML_FILTER_EL_ID						"filter"
#define XML_ATTR_ACTIVE							"active"
#define XML_ATTR_NAME							"name"
#define XML_RULE_EL_NAME						"rule"
#define XML_ATTR_OPERATION						"op"
#define XML_ATTR_VALUE							"val"

//MAC
#define XML_MACLIST_ROOT_EL_NAME				"maclist"
#define XML_ATTR_BLOCK_OTHR						"block_others"
#define	XML_MAC_EL								"mac"
#define	XML_ATTR_MAC_SCHED						"sched"
#define	XML_ATTR_MAC_ENBL_SCHED					"sched_enbl"

//Colors
#define XML_ATTR_RECV_COLOR						"clr_recv"
#define XML_ATTR_TRNS_COLOR						"clr_transm"

//Notify
#define XML_ATTR_SMTP_SERVER					"smtp_srv"
#define XML_ATTR_SMTP_SERVERPORT				"smtp_srv_port"
#define XML_ATTR_SMTP_USER						"smtp_user"
#define XML_ATTR_SMTP_PASSW						"smtp_passw"
#define XML_ATTR_SMTP_SEND_APP_LOG				"smtp_app_log"
#define XML_ATTR_SMTP_SEND_SYS_LOG				"smtp_sys_log"
#define XML_ATTR_SMTP_SEND_INT					"smtp_send_int"
#define XML_ATTR_SMTP_FROM						"smtp_from"
#define XML_ATTR_SMTP_TO						"smtp_to"
#define XML_ATTR_SMTP_SEND_SYS_LOG_LEVEL		"smtp_save_syslog_level"

//Advanced opt
#define XML_TAG_ENTRY							"entry"

//GUI
#define XML_ATTR_SHOW_HP						"gui_show_hp"
#define XML_ATTR_GUI_UPDT_INT					"gui_updt_speed"
#define XML_ATTR_UPD_CHECK						"gui_check_upd"

//Port Forwarding
#define XML_ATTR_PF_AUTO						"pf_auto"
#define XML_ATTR_PW_AUTO_ST						"pf_auto_st"
#define XML_ATTR_PF_ENABLE_ALLOW_POLICY			"pf_allow_policy"
#define XML_ATTR_PF_ALLOW_POLICY				"pf_allow"
#define XML_ATTR_PF_ENABLE_BLOCK_POLICY			"pf_block_policy"
#define XML_ATTR_PF_BLOCK_POLICY				"pf_block"



#define XML_ATTR_PROTO			"proto"
#define XML_ATTR_IP				"ip"
#define XML_ATTR_FROM			"from"
#define XML_ATTR_FROM_TO		"from_to"
#define XML_ATTR_TO				"to"
#define XML_ATTR_ENABLED		"enabled"

//Reboot sched
#define XML_ATTR_REBOOT_SC		"sched_reboot"
#define XML_ATTR_REBOOT_SC_ENBL "sched_reboot_enbl"

//Log
#define XML_ATTR_APPLOG_SAVE_ENBL	"applog_save_enbl"
#define XML_ATTR_APPLOG_FN			"applog_save_flnm"
#define XML_ATTR_APPLOG_LIM			"applog_save_lim"
#define XML_ATTR_APPLOG_INT			"applog_int"
#define XML_ATTR_APPLOG_PERF_ENBL	"applog_perf_enbl"
#define XML_ATTR_APPLOG_CONN_ENBL	"applog_conn_enbl"
#define XML_ATTR_APPLOG_BNDW_ENBL	"applog_bndw_enbl"
#define XML_ATTR_APPLOG_ACCSS_ENBL	"applog_acc_enbl"
#define XML_ATTR_APPLOG_ADSL_ENBL	"applog_adsl_enbl"
#define XML_ATTR_APPLOG_WRLSS_ENBL	"applog_wrlss_enbl"
#define XML_ATTR_APPLOG_PING_ENBL	"applog_ping_enbl"

//Ping
#define XML_ATTR_INT				"intrvl"
#define XML_ATTR_ACTION_CNT			"act_cnt"
#define XML_ATTR_ACTION				"act"
#define XML_ATTR_FILE				"file"
#define XML_ATTR_COLOR				"color"
#define XML_ATTR_STATUS				"status"

CPropertyStorage::CPropertyStorage(CConfigData& cfgStorage, CGUILogic& logic):m_cfgStorage(cfgStorage),
	m_logic(logic)
{
	m_doc.AddElem( XML_ROOT_EL_NAME );
}

CPropertyStorage::~CPropertyStorage(void)
{
}

bool CPropertyStorage::IsChanged(PANELTYPE pt, const PROPENTRY& pp)
{
	PROPS::iterator iCur = m_props.find(pt);

	if ( iCur!=m_props.end() )
	{
		return pp.tLastChange != iCur->second.tLastChange;
	}

	return false;
}

void CPropertyStorage::GetProperty(PANELTYPE pt, PROPENTRY& pp)
{
	PROPS::iterator iCur = m_props.find(pt);

	if ( iCur!=m_props.end() )
	{
		pp = iCur->second;
	}
}

void CPropertyStorage::SetProperty(PANELTYPE pt, const PROPENTRY& val )
{
	PROPENTRY old;
	GetProperty(pt, old);

	//if changed
	if ( old!=val )
	{
		PROPENTRY copy=val;
		copy.tLastChange = time(NULL);
		m_props[pt] = copy;
	}
}

//build xml
void CPropertyStorage::Save()
{
	m_doc.ResetPos();

	while ( m_doc.FindChildElem(XML_EL_ID) )
	{
		m_doc.RemoveChildElem();
	}

	m_doc.ResetPos();

	while ( m_doc.FindChildElem(XML_SYSLOG_EL_ID) )
	{
		m_doc.RemoveChildElem();
	}
	
	m_doc.ResetPos();
	m_doc.FindElem(XML_ROOT_EL_NAME);

	for ( PROPS::iterator iCur=m_props.begin();iCur!=m_props.end();iCur++ )
	{
		PROPENTRY& entry = iCur->second;
		
		wxString scrptWrn = entry.onWarningScript; /*wxBase64Encode( entry.onWarningScript.ToAscii(), entry.onWarningScript.size() )*/;
		wxString scrptAlr = entry.onAlarmScript;   /*wxBase64Encode( entry.onAlarmScript.ToAscii(), entry.onAlarmScript.size() )*/;
		
		m_doc.AddChildElem( XML_EL_ID );
		m_doc.AddChildAttrib( XML_ATTR_ID, (int)iCur->first );
		m_doc.AddChildAttrib( XML_ATTR_WRN_LEVEL, entry.btWarningLevel );
		m_doc.AddChildAttrib( XML_ATTR_ALR_LEVEL, entry.btAlarmLevel );
		m_doc.AddChildAttrib( XML_ATTR_WRN_STRAT, entry.onWarning );
		m_doc.AddChildAttrib( XML_ATTR_ALR_STRAT, entry.onAlarm );
		m_doc.AddChildAttrib( XML_ATTR_ALR_STRAT, entry.onAlarm );
		m_doc.AddChildAttrib( XML_ATTR_REPAIR, entry.bEnableRepair?XML_VAL_TRUE:XML_VAL_FALSE );
		//doc.AddChildAttrib( XML_ATTR_WRN_SCRIPT, scrptWrn.ToAscii() );
		//doc.AddChildAttrib( XML_ATTR_ALR_SCRIPT, scrptAlr.ToAscii() );
	}

	m_doc.ResetPos();
	m_doc.FindElem(XML_ROOT_EL_NAME);

	for ( SYSLOGACTIONS::iterator iCur=m_syslogactions.begin();iCur!=m_syslogactions.end();iCur++ )
	{
		SYSLOGACTION& entry = iCur->second;

		m_doc.AddChildElem( XML_SYSLOG_EL_ID );
		m_doc.AddChildAttrib( XML_ATTR_SLOG_ID, (int)iCur->first );
		m_doc.AddChildAttrib( XML_ATTR_SLOG_PATT, entry.strPattern.ToAscii() );
		m_doc.AddChildAttrib( XML_ATTR_SLOG_ACT, entry.recvStrat );

		if ( entry.recvStrat == cRCACTScript )
		{
			m_doc.AddChildAttrib( XML_ATTR_SLOG_RUN, entry.strScriptName.ToAscii() );
		}
	}
	
	
	const char* szDoc = m_doc.GetDoc().c_str();
	m_cfgStorage.SetProperties( wxString::FromAscii( szDoc ) );
}

void CPropertyStorage::Load()
{
	wxString strProp;
	
	try
	{
		strProp = m_cfgStorage.GetProperties();
		
		if ( !m_doc.SetDoc( strProp.ToAscii()) ) THROW_EXC(cERWrongObjectState);
		
		while ( m_doc.FindChildElem(XML_EL_ID) )
		{
			PANELTYPE pt;
			PROPENTRY entry;
			
			pt = (PANELTYPE)atol( m_doc.GetChildAttrib( XML_ATTR_ID).c_str() );
			
			if ( !pt ) THROW_EXC(cERWrongObjectState);
			
			entry.btWarningLevel = (unsigned char)atol( m_doc.GetChildAttrib( XML_ATTR_WRN_LEVEL).c_str() );
			entry.btAlarmLevel = (unsigned char)atol( m_doc.GetChildAttrib( XML_ATTR_ALR_LEVEL).c_str() );
			entry.onWarning = (RECOVERYSTRAT)atol( m_doc.GetChildAttrib( XML_ATTR_WRN_STRAT ).c_str() );
			entry.onAlarm = (RECOVERYSTRAT)atol( m_doc.GetChildAttrib( XML_ATTR_ALR_STRAT).c_str() );
			entry.bEnableRepair = m_doc.GetChildAttrib( XML_ATTR_REPAIR ) == XML_VAL_TRUE; 
			
			SetProperty( pt, entry );
		}

		m_doc.ResetPos();

		while ( m_doc.FindChildElem(XML_SYSLOG_EL_ID) )
		{
			cRecoveryStrategy strat = (cRecoveryStrategy)atol( m_doc.GetChildAttrib( XML_ATTR_SLOG_ACT).c_str() );
			long lID = atol( m_doc.GetChildAttrib( XML_ATTR_SLOG_ID).c_str() );
			std::string strPatt = m_doc.GetChildAttrib( XML_ATTR_SLOG_PATT);
			std::string strRun  = m_doc.GetChildAttrib( XML_ATTR_SLOG_RUN);

			SYSLOGACTION action;

			action.strPattern = wxString::FromAscii( strPatt.c_str() );
			action.strPattern = action.strPattern.Trim();
			action.strPattern = action.strPattern.Trim(false);
			action.recvStrat = strat;

			if ( action.recvStrat == cRCACTScript )
			{
				action.strScriptName = wxString::FromAscii( strRun.c_str() );

				if ( action.strScriptName.empty() )
				{
					action.recvStrat = cRCACTNothing;
				}
			}

			if ( !action.strPattern.IsEmpty() )
				m_syslogactions[ (unsigned char)lID ] = action;
		}
	}
	catch(...)
	{
		LoadDefault();
	}
}

void CPropertyStorage::LoadDefault()
{
	PROPENTRY entry;

	//Nat
	entry.bEnableRepair = true;
	entry.btWarningLevel=80;
	entry.btAlarmLevel=95;
	entry.onWarning=cRCACTNothing;
	entry.onAlarm=cRCACTReboot;
	SetProperty( cPTNAT, entry );
	
	//Memory
	entry.btWarningLevel=80;
	entry.btAlarmLevel=99;
	entry.onWarning=cRCACTNothing;
	entry.onAlarm=cRCACTNothing;
	SetProperty( cPTMem, entry );

	//Route
	entry.btWarningLevel=90;
	entry.btAlarmLevel=95;
	entry.onWarning=cRCACTFlush;
	entry.onAlarm=cRCACTFlush;
	SetProperty( cPTRoute, entry );

	//cPTCPU
	entry.btWarningLevel=80;
	entry.btAlarmLevel=99;
	entry.onWarning=cRCACTNothing;
	entry.onAlarm=cRCACTReboot;
	SetProperty( cPTCPU, entry );

	//Enable NAT optimization by default
	SetEnableNATOpt(true);

	//Enable NAT table size optimization by default
	SetEnableNATSizeOpt(true);

	SetBootRun(true);

	//Port forward block list
	TEXTLIST lstPF;
	lstPF.push_back("System");
	lstPF.push_back("advapi");
	lstPF.push_back("vmware-authd.exe");

	SetBlockPFPolicy(lstPF);
	


	//Proc Kill List
	TEXTLIST lst;
	lst.push_back("tr69c");
	lst.push_back("tr64");
	lst.push_back("siproxd");
	

	SetProcKillList( lst );

	//Mod Unload List
	TEXTLIST lstMod;
	lstMod.push_back("ip_nat_h323");
	lstMod.push_back("ip_conntrack_h323");
	lstMod.push_back("ip_nat_sip");
	lstMod.push_back("ip_conntrack_sip");
	SetModUnloadList( lstMod );


	//All messages  by default
	SetSysLogFromRouterOnly(false);

	//Enable auto port forwarding
	SetAutoPortForward( true );

	//Add drop packet by default to reboot
	SYSLOGACTIONS	acts;
	SYSLOGACTION	action;

	action.strPattern = wxT("table full, dropping packet");
	action.recvStrat = cRCACTReboot;

	acts[0] = action;

	SetSysLogActions(acts);
}

bool CPropertyStorage::GetBoolProperty(const char* szProp, bool bDef)
{
	m_doc.ResetPos();
	m_doc.FindElem(XML_ROOT_EL_NAME);

	std::string strProp = m_doc.GetAttrib(szProp);

	if ( strProp.empty() )
		return bDef;

	return strProp==XML_VAL_TRUE;
}

void CPropertyStorage::SetBoolProperty(const char* szProp, bool bVal)
{
	m_doc.ResetPos();
	m_doc.FindElem(XML_ROOT_EL_NAME);

	m_doc.SetAttrib(szProp, bVal?XML_VAL_TRUE:XML_VAL_FALSE);

	Save();
}

wxString CPropertyStorage::GetStringProperty(const char* szProp)
{
	return wxString::FromAscii( GetStringPropertyAscii(szProp).c_str() );
}

std::string	CPropertyStorage::GetStringPropertyAscii(const char* szProp)
{
	m_doc.ResetPos();
	m_doc.FindElem(XML_ROOT_EL_NAME);

	return m_doc.GetAttrib(szProp);
}

void CPropertyStorage::SetStringProperty(const char* szProp, const wxString& strVal)
{
	SetStringPropertyAscii( szProp, (const char*)strVal.ToAscii() );
}

void CPropertyStorage::SetStringPropertyAscii(const char* szProp, const std::string& strVal)
{
	m_doc.ResetPos();
	m_doc.FindElem(XML_ROOT_EL_NAME);
	m_doc.SetAttrib(szProp, strVal.c_str() );

	Save();
}


long CPropertyStorage::GetLongProperty(const char* szProp, long def)
{
	m_doc.ResetPos();
	m_doc.FindElem(XML_ROOT_EL_NAME);

	std::string strVal = m_doc.GetAttrib(szProp);

	return strVal.empty()?def:atol(strVal.c_str());
}

void CPropertyStorage::SetLongProperty(const char* szProp, long lVal)
{
	m_doc.ResetPos();
	m_doc.FindElem(XML_ROOT_EL_NAME);
	m_doc.SetAttrib(szProp, lVal );

	Save();
}

TEXTLIST CPropertyStorage::GetStringList(const char* szListID)
{
	TEXTLIST lst;

	m_doc.ResetPos();
	m_doc.FindElem(XML_ROOT_EL_NAME);

	std::stringstream sIn( m_doc.GetAttrib(szListID).c_str() );

	char buf[512];

	while ( !sIn.getline(buf, sizeof(buf), DELIM_STR_LIST).eof() )
	{
		size_t stLen = strlen(buf);

		if ( stLen )
		{
			lst.push_back( buf );
		}
	}

	return lst;
}

void CPropertyStorage::SetStringList(const char* szListID, const TEXTLIST& lst )
{
	std::string str;
	TEXTLIST lstSaved;
	
	for ( size_t i=0;i<lst.size();i++ )
	{
		bool bSaveIt(true);

		//Do not save duplicates
		for ( size_t j=0;j<lstSaved.size();j++ )
		{
			if ( lstSaved[j] == lst[i] )
			{
				bSaveIt = false;
				break;
			}
		}

		if (!bSaveIt) continue;
		
		lstSaved.push_back(lst[i]);

		str+=lst[i];
		str+=DELIM_STR_LIST;
	}

	m_doc.ResetPos();
	m_doc.FindElem(XML_ROOT_EL_NAME);
	m_doc.SetAttrib(szListID, str.c_str() );

	Save();
}

//////////////////////////////////////////////////////////////////////////
//General options

//Run at startup
bool CPropertyStorage::GetBootRun()
{
	return CSysDepAPI::IsLoadedAtStartUp();
}

void CPropertyStorage::SetBootRun(bool bVal)
{
	CSysDepAPI::SetLoadAtStartUp(bVal);
}

//Language
long CPropertyStorage::GetLanguage()
{
	long lVal(wxLANGUAGE_DEFAULT);
	
	try
	{
		lVal = m_cfgStorage.GetLangId();
	}
	catch(...) {}
	
	return lVal;
}

void CPropertyStorage::SetLanguage(long val)
{
	try
	{
		m_cfgStorage.SetLangId(val);
	}catch(...) {}
}

//NAT Optimization
bool CPropertyStorage::GetEnableNATOpt()
{
	return GetBoolProperty( XML_ATTR_ENABLE_NAT_OPT );
}

void CPropertyStorage::SetEnableNATOpt(bool bVal)
{
	SetBoolProperty( XML_ATTR_ENABLE_NAT_OPT, bVal );
}

//NAT Size Optimization
bool CPropertyStorage::GetEnableNATSizeOpt()
{
	return GetBoolProperty( XML_ATTR_ENABLE_NAT_SZ_OPT );
}

void CPropertyStorage::SetEnableNATSizeOpt(bool bVal)
{
	SetBoolProperty( XML_ATTR_ENABLE_NAT_SZ_OPT, bVal );
}

//Peer To Peer
bool CPropertyStorage::GetEnableP2PNetworkOpt()
{
	return GetBoolProperty( XML_ATTR_ENABLE_P2P_OPT );
}

void CPropertyStorage::SetEnableP2PNetworkOpt(bool bVal)
{
	SetBoolProperty( XML_ATTR_ENABLE_P2P_OPT, bVal );
}

//WWW
bool CPropertyStorage::GetEnableWWWOpt()
{
	return GetBoolProperty( XML_ATTR_ENABLE_WWW_OPT );
}

void CPropertyStorage::SetEnableWWWOpt(bool bVal)
{
	SetBoolProperty( XML_ATTR_ENABLE_WWW_OPT, bVal );
}



//TCP
bool CPropertyStorage::GetEnableTCPOpt()
{
	return GetBoolProperty( XML_ATTR_ENABLE_TCP_OPT );
}

void CPropertyStorage::SetEnableTCPOpt(bool bVal)
{
	SetBoolProperty( XML_ATTR_ENABLE_TCP_OPT, bVal );
}

//icmp
bool CPropertyStorage::GetEnableICMPOpt()
{
	return GetBoolProperty( XML_ATTR_ENABLE_ICMP_OPT );
}

void CPropertyStorage::SetEnableICMPOpt(bool bVal)
{
	SetBoolProperty( XML_ATTR_ENABLE_ICMP_OPT, bVal );
}

//advanced
bool CPropertyStorage::GetEnableAdvancedOpt()
{
	return GetBoolProperty( XML_ATTR_ENABLE_ADVANCED_OPT );
}

void CPropertyStorage::SetEnableAdvancedOpt(bool bVal)
{
	SetBoolProperty( XML_ATTR_ENABLE_ADVANCED_OPT, bVal );
}

//advanced opt list
STRINGPAIRLIST CPropertyStorage::GetAdvancedOptList()
{
	STRINGPAIRLIST lst;

	try
	{
		wxString str = m_cfgStorage.GetAdvancedOptXML();

		CMarkupSTL	doc;

		if ( doc.SetDoc(str.ToAscii()) )
		{
			while ( doc.FindChildElem(XML_TAG_ENTRY) )
			{
				STRINGPAIR pair;

				pair.strLabel  = wxString::FromAscii( doc.GetChildAttrib(XML_ATTR_NAME).c_str() );
				pair.strVal = wxString::FromAscii( doc.GetChildData().c_str() );
				lst.push_back(pair);
			}
		}
	}
	catch(...)
	{
	}

	return lst;
}

void CPropertyStorage::SetAdvancedOptListProperty(const wxString& strProp,
												 const wxString& strVal)
{
	STRINGPAIRLIST lst = GetAdvancedOptList();
	STRINGPAIRLIST::iterator iCur;

	for ( iCur=lst.begin();iCur!=lst.end();iCur++ )
	{
		STRINGPAIR& pair = *iCur;

		if ( strProp == pair.strLabel )
		{
			pair.strVal = strVal;
			break;
		}
	}

	if ( iCur==lst.end() )
	{
		STRINGPAIR pair = {strProp, strVal};
		lst.push_back(pair);
	}

	SetAdvancedOptList(lst);
}


void CPropertyStorage::SetAdvancedOptList(const STRINGPAIRLIST& val)
{
	try
	{
		CMarkupSTL	doc;
		doc.AddElem( "opt_advanced" );

		for ( STRINGPAIRLIST::const_iterator iCur=val.begin();iCur!=val.end();iCur++ )
		{
			const STRINGPAIR& pair = *iCur;
			doc.AddChildElem( XML_TAG_ENTRY, (const char*) pair.strVal.ToAscii()  );
			doc.AddChildAttrib( XML_ATTR_NAME,  (const char*) pair.strLabel.ToAscii() );
		}

		const char* szDoc = doc.GetDoc().c_str();
		m_cfgStorage.SetAdvancedOptXML( wxString::FromAscii( szDoc ) );
	}
	catch(...)
	{
	}
}

//Start up script
void CPropertyStorage::SetEnableStartUpScript( bool bVal )
{
	SetBoolProperty( XML_ATTR_ENABLE_STUP_SC, bVal );
}

bool CPropertyStorage::GetEnableStartUpScript()
{
	return GetBoolProperty( XML_ATTR_ENABLE_STUP_SC) &&
		!GetStartUpScriptFileName().empty();
}

void CPropertyStorage::SetStartUpScriptFileName( const wxString& str )
{
	SetStringProperty( XML_ATTR_ENABLE_STUP_SC_FN, str );
}

wxString CPropertyStorage::GetStartUpScriptFileName()
{
	return GetStringProperty( XML_ATTR_ENABLE_STUP_SC_FN );
}


//Proc Kill
void CPropertyStorage::SetEnableProcKill( bool bSet )
{
	SetBoolProperty( XML_ATTR_ENABLE_PROC_KILL, bSet );
}

bool CPropertyStorage::GetEnableProcKill()
{
	return GetBoolProperty( XML_ATTR_ENABLE_PROC_KILL, true);
}

TEXTLIST CPropertyStorage::GetProcKillList()
{
	return GetStringList(PROC_LIST_ID);
}

void CPropertyStorage::SetProcKillList(const TEXTLIST& val)
{
	SetStringList(PROC_LIST_ID, val);
}

//Mod Unload
void CPropertyStorage::SetEnableModUnload( bool bSet )
{
	SetBoolProperty( XML_ATTR_ENABLE_MOD_UNLOAD, bSet );
}

bool CPropertyStorage::GetEnableModUnload()
{
	return GetBoolProperty( XML_ATTR_ENABLE_MOD_UNLOAD, true );
}

TEXTLIST CPropertyStorage::GetModUnloadList()
{
	return GetStringList(MOD_LIST_ID);
}

void CPropertyStorage::SetModUnloadList(const TEXTLIST& val)
{
	SetStringList( MOD_LIST_ID, val );
}


//Syslog from router only
bool CPropertyStorage::GetSysLogFromRouterOnly()
{
	return GetBoolProperty( XML_ATTR_SYSLOG_FROMRONLY_OPT );
}

void CPropertyStorage::SetSysLogFromRouterOnly(bool bVal)
{
	SetBoolProperty( XML_ATTR_SYSLOG_FROMRONLY_OPT, bVal );
}

//Syslog log blocked MACs
bool CPropertyStorage::GetLogBlockedMAC()
{
	return GetBoolProperty( XML_ATTR_SYSLOG_LOGMACBLOCK_OPT );
}

void CPropertyStorage::SetLogBlockedMAC(bool bVal)
{
	SetBoolProperty( XML_ATTR_SYSLOG_LOGMACBLOCK_OPT, bVal );
}

//Syslog enable auto log save
void CPropertyStorage::SetEnableSyslogSave( bool bVal )
{
	SetBoolProperty( XML_ATTR_SYSLOG_ENABLEAUTOSAVE_OPT, bVal );
}

bool CPropertyStorage::GetEnableSyslogSave()
{
	return GetBoolProperty( XML_ATTR_SYSLOG_ENABLEAUTOSAVE_OPT, false );
}

//Syslog log file name
void CPropertyStorage::SetSyslogSaveFileName( const wxString& str )
{
	SetStringProperty(XML_ATTR_SYSLOG_FILE_OPT_2, str);
}

wxString CPropertyStorage::GetSyslogSaveFileName()
{
	return GetStringProperty(XML_ATTR_SYSLOG_FILE_OPT_2);
}

//Syslog log file limit
void CPropertyStorage::SetSyslogSaveLimit( long lLimit )
{
	SetLongProperty(XML_ATTR_SYSLOG_FILELIMIT_OPT, lLimit);
}

long CPropertyStorage::GetSyslogSaveLimit()
{
	return GetLongProperty(XML_ATTR_SYSLOG_FILELIMIT_OPT, UNLIMITED_SIZE );
}

//Syslog Port
void CPropertyStorage::SetSysLogUDPPort(long lLimit)
{
	SetLongProperty(XML_ATTR_SYSLOG_UDP_PORT, lLimit);
}

long CPropertyStorage::GetSysLogUDPPort()
{
	return GetLongProperty(XML_ATTR_SYSLOG_UDP_PORT, DEF_SYSLOG_PORT );
}

//Syslog autoconfig
void CPropertyStorage::SetEnableSyslogAutoConfig( bool bVal )
{
	SetBoolProperty( XML_ATTR_SYSLOG_AUTO_CONF, bVal );
}

bool CPropertyStorage::GetEnableSyslogAutoConfig()
{
	return GetBoolProperty( XML_ATTR_SYSLOG_AUTO_CONF, true );
}

void CPropertyStorage::SetSyslogAutoConfigLevel(long lLimit)
{
	SetLongProperty(XML_ATTR_SYSLOG_AUTO_CONF_LVL, lLimit);
}

long CPropertyStorage::GetSyslogAutoConfigLevel()
{
	return GetLongProperty(XML_ATTR_SYSLOG_AUTO_CONF_LVL, 4);
}


//Syslog actions
SYSLOGACTIONS CPropertyStorage::GetSysLogActions()
{
	return m_syslogactions;
}

void CPropertyStorage::SetSysLogActions(const SYSLOGACTIONS& act)
{
	m_syslogactions = act;
}

//Search filter
void CPropertyStorage::SetSearchFilters(cSearchOwnerID cID, const FILTERS& filters)
{
	CMarkupSTL	doc;
	doc.AddElem( XML_FILTER_ROOT_EL_NAME );

	doc.ResetPos();

	while ( doc.FindChildElem(XML_FILTER_EL_ID) )
	{
		doc.RemoveChildElem();
	}

	doc.ResetPos();
	doc.FindElem(XML_FILTER_ROOT_EL_NAME);

	for ( FILTERS::const_iterator iCur=filters.begin();iCur!=filters.end();iCur++ )
	{
		const FILTER& filter = *iCur;

		//Save user defined filters only
		if ( filter.bSysDef ) continue;

		doc.AddChildElem( XML_FILTER_EL_ID );
		doc.AddChildAttrib( XML_ATTR_ACTIVE,  filter.bActive?XML_VAL_TRUE: XML_VAL_FALSE );
		doc.AddChildAttrib( XML_ATTR_NAME,  filter.strFilterName.ToUTF8() );

		doc.IntoElem();

		for ( FIELDRULESET::const_iterator iRule=filter.filterDef.begin();
			iRule!=filter.filterDef.end();iRule++ )
		{
			doc.AddChildElem( XML_RULE_EL_NAME );
			doc.AddChildAttrib( XML_ATTR_ID, (int)iRule->iFieldID );
			doc.AddChildAttrib( XML_ATTR_OPERATION, (int)iRule->rule );
			doc.AddChildAttrib( XML_ATTR_VALUE, iRule->strVal.ToUTF8() );
		}

		doc.OutOfElem();
	}

	const char* szDoc = doc.GetDoc().c_str();
	m_cfgStorage.SetFilters( cID, wxString::FromAscii( szDoc ) );
}

FILTERS CPropertyStorage::GetSearchFilters(cSearchOwnerID cID )
{
	FILTERS filters;
	
	try
	{
		CMarkupSTL	doc;
		wxString strFilters;
		strFilters = m_cfgStorage.GetFilters(cID);
		
		if ( !doc.SetDoc( strFilters.ToAscii()) ) THROW_EXC(cERWrongObjectState);
		
		while ( doc.FindChildElem(XML_FILTER_EL_ID) )
		{
			FILTER filter;

			filter.bActive = doc.GetChildAttrib(XML_ATTR_ACTIVE)==XML_VAL_TRUE;
			filter.strFilterName = wxString::FromUTF8( doc.GetChildAttrib(XML_ATTR_NAME).c_str() );

			doc.IntoElem();

			while ( doc.FindChildElem(XML_RULE_EL_NAME) )
			{
				FILTERFIELDRULE rule;

				rule.iFieldID =  (int)atol( doc.GetChildAttrib(XML_ATTR_ID).c_str() );
				rule.rule = (cFilterRule)atol( doc.GetChildAttrib( XML_ATTR_OPERATION).c_str() );
				rule.strVal = wxString::FromUTF8( doc.GetChildAttrib(XML_ATTR_VALUE).c_str() );

				filter.filterDef.push_back(rule);
			}

			doc.OutOfElem();

			filters.push_back(filter);
		}
	}
	catch(...)
	{
	}

	m_logic.OnFilterLoaded(cID, filters);

	return filters;
}

//MAC list
void CPropertyStorage::SetMACList(const MACBLOCK& lstMAC)
{
	CMarkupSTL	doc;
	doc.AddElem( XML_MACLIST_ROOT_EL_NAME );
	doc.AddAttrib( XML_ATTR_BLOCK_OTHR, lstMAC.blockOthers?XML_VAL_TRUE: XML_VAL_FALSE );

	for ( MACLIST::const_iterator iCur=lstMAC.list.begin();iCur!=lstMAC.list.end();iCur++ )
	{
		doc.AddChildElem( XML_MAC_EL, iCur->strMAC.c_str() );
		doc.AddChildAttrib(XML_ATTR_MAC_SCHED, iCur->SchedToString().c_str() );
		doc.AddChildAttrib(XML_ATTR_MAC_ENBL_SCHED, iCur->bEnableSched?XML_VAL_TRUE:XML_VAL_FALSE );
	}

	const char* szDoc = doc.GetDoc().c_str();
	m_cfgStorage.SetMACList( lstMAC.id, wxString::FromAscii( szDoc ) );
}

MACBLOCK CPropertyStorage::GetMACList(cMACBlockRuleId cID)
{
	MACBLOCK lstRet;
	lstRet.id = cID;
	lstRet.blockOthers = false;
	
	try
	{
		CMarkupSTL	doc;
		wxString strVal;
		strVal = m_cfgStorage.GetMACList(cID);
		
		if ( !doc.SetDoc( strVal.ToAscii()) ) THROW_EXC(cERWrongObjectState);
		if ( !doc.FindElem(XML_MACLIST_ROOT_EL_NAME) ) THROW_EXC(cERWrongObjectState);

		lstRet.blockOthers = doc.GetAttrib(XML_ATTR_BLOCK_OTHR)==XML_VAL_TRUE;

		while ( doc.FindChildElem(XML_MAC_EL) )
		{
			MACENTRY entry;
			entry.strMAC = doc.GetChildData();
			entry.SchedFromString( doc.GetChildAttrib(XML_ATTR_MAC_SCHED) );
			entry.bEnableSched = doc.GetChildAttrib(XML_ATTR_MAC_ENBL_SCHED)==XML_VAL_TRUE;

			lstRet.list.push_back(entry);
		}
	}
	catch(...)
	{
	}

	if ( cID!=cMACBlockRuleIdWL )
		lstRet.blockOthers = false;

	return lstRet;
}

void CPropertyStorage::SetRecvColor( const wxColor& clr )
{
	SetStringProperty( XML_ATTR_RECV_COLOR, clr.GetAsString() );
}

wxColor  CPropertyStorage::GetRecvColor()
{
	wxString str = GetStringProperty( XML_ATTR_RECV_COLOR);

	if ( str.IsEmpty() )
		return wxColor(0, 128, 255);
	else return wxColor(str);
}

void CPropertyStorage::SetTransmColor( const wxColor& clr )
{
	SetStringProperty( XML_ATTR_TRNS_COLOR, clr.GetAsString() );
}

wxColor  CPropertyStorage::GetTransmColor()
{
	wxString str = GetStringProperty( XML_ATTR_TRNS_COLOR );

	if ( str.IsEmpty() )
		return wxColor(255, 128, 128);
	else return wxColor(str);
}

//SMTP Server
wxString CPropertyStorage::GetSMTPServer()
{
	return GetStringProperty( XML_ATTR_SMTP_SERVER );
}

void CPropertyStorage::SetSMTPServer(const wxString& str)
{
	SetStringProperty( XML_ATTR_SMTP_SERVER, str );
}

//SMTP Server Port
unsigned short CPropertyStorage::GetSMTPServerPort()
{
	return (unsigned short)GetLongProperty(XML_ATTR_SMTP_SERVERPORT, 25);
}

void CPropertyStorage::SetSMTPServerPort(unsigned short wPort)
{
	SetLongProperty(XML_ATTR_SMTP_SERVERPORT, wPort);
}


//SMTP User
wxString CPropertyStorage::GetSMTPUser()
{
	return GetStringProperty( XML_ATTR_SMTP_USER );
}

void CPropertyStorage::SetSMTPUser(const wxString& str)
{
	SetStringProperty( XML_ATTR_SMTP_USER, str );
}

//SMTP Passw
wxString CPropertyStorage::GetSMTPPassw()
{
	return GetStringProperty( XML_ATTR_SMTP_PASSW );
}

void CPropertyStorage::SetSMTPPassw(const wxString& str)
{
	SetStringProperty( XML_ATTR_SMTP_PASSW, str );
}

//SMTP From
wxString CPropertyStorage::GetSMTPFrom()
{
	return GetStringProperty( XML_ATTR_SMTP_FROM );
}

void CPropertyStorage::SetSMTPFrom(const wxString& str)
{
	SetStringProperty( XML_ATTR_SMTP_FROM, str );
}

//SMTP To
wxString CPropertyStorage::GetSMTPTo()
{
	return GetStringProperty( XML_ATTR_SMTP_TO );
}

void CPropertyStorage::SetSMTPTo(const wxString& str)
{
	SetStringProperty( XML_ATTR_SMTP_TO, str );
}

//Send application Log
bool CPropertyStorage::GetSendAppLog()
{
	return GetBoolProperty( XML_ATTR_SMTP_SEND_APP_LOG );
}

void CPropertyStorage::SetSendAppLog(bool bVal)
{
	SetBoolProperty( XML_ATTR_SMTP_SEND_APP_LOG, bVal );
}

//Send syslog Log
bool CPropertyStorage::GetSendSysLog()
{
	return GetBoolProperty( XML_ATTR_SMTP_SEND_SYS_LOG );
}

void CPropertyStorage::SetSendSysLog(bool bVal)
{
	SetBoolProperty( XML_ATTR_SMTP_SEND_SYS_LOG, bVal );
}

//Syslog email send level
long CPropertyStorage::GetSyslogSendLevel()
{
	//default 3 - error level
	return GetLongProperty(XML_ATTR_SMTP_SEND_SYS_LOG_LEVEL, 3);
}

void CPropertyStorage::SetSyslogSendLevel(long lLevel)
{
	SetLongProperty(XML_ATTR_SMTP_SEND_SYS_LOG_LEVEL, lLevel);
}


//Send interval
time_t CPropertyStorage::GetSendPeriod()
{
	return (time_t)GetLongProperty(XML_ATTR_SMTP_SEND_INT,60*60);
}

void CPropertyStorage::SetSendPeriod(time_t t)
{
	SetLongProperty(XML_ATTR_SMTP_SEND_INT, (long)t);
}

//GUI: Show help panel
bool CPropertyStorage::GetShowHelpPanel()
{
	return GetBoolProperty( XML_ATTR_SHOW_HP, true );
}

void CPropertyStorage::SetShowHelpPanel(bool bVal)
{
	SetBoolProperty( XML_ATTR_SHOW_HP, bVal );
}

//GUI: Update speed
time_t CPropertyStorage::GetUpdateSpeed()
{
	return (time_t)GetLongProperty(XML_ATTR_GUI_UPDT_INT, NORMAL_UPDATE_SPEED);
}

void CPropertyStorage::SetUpdateSpeed(time_t t)
{
	SetLongProperty(XML_ATTR_GUI_UPDT_INT, (long)t);
}

//Port forwarding
bool CPropertyStorage::GetAutoPortForward()
{
	return GetBoolProperty( XML_ATTR_PF_AUTO );
}

void CPropertyStorage::SetAutoPortForward(bool bVal)
{
	SetBoolProperty( XML_ATTR_PF_AUTO, bVal );
}

unsigned short  CPropertyStorage::GetAutoPortForwardLowPort()
{
	return (unsigned short)GetLongProperty(XML_ATTR_PW_AUTO_ST, DEFAULT_AUTO_PF_LOW_BOUND);
}

void CPropertyStorage::SetAutoPortForwardLowPort(unsigned short val)
{
	SetLongProperty(XML_ATTR_PW_AUTO_ST, (long)val);
}

PORTFORWARDLIST CPropertyStorage::GetPortForwardLst()
{
	PORTFORWARDLIST lst;

	try
	{
		wxString str = m_cfgStorage.GetPortForwardXML();

		CMarkupSTL	doc;

		if ( doc.SetDoc(str.ToAscii()) )
		{
			while ( doc.FindChildElem(XML_TAG_ENTRY) )
			{
				PORTFORWARDRULE rule;

				rule.strLabel  = wxString::FromAscii( doc.GetChildAttrib(XML_ATTR_NAME).c_str() );
				rule.proto = (cPortFrorwardProto)atol( doc.GetChildAttrib(XML_ATTR_PROTO).c_str() );
				rule.strDst  = wxString::FromAscii( doc.GetChildAttrib(XML_ATTR_IP).c_str() );
				rule.wPortFrom = (unsigned short)atol( doc.GetChildAttrib(XML_ATTR_FROM).c_str() );
				rule.wPortFromTo = (unsigned short)atol( doc.GetChildAttrib(XML_ATTR_FROM_TO).c_str() );

				if (!rule.wPortFromTo)
					rule.wPortFromTo = rule.wPortFrom;

				rule.wPortTo  = (unsigned short)atol( doc.GetChildAttrib(XML_ATTR_TO).c_str() );
				rule.bEnabled = doc.GetChildAttrib(XML_ATTR_ENABLED)!=XML_VAL_FALSE;
				lst.push_back(rule);
			}
		}
	}
	catch(...)
	{
	}

	return lst;
}

void CPropertyStorage::SetPortForwardLst(const PORTFORWARDLIST& lst)
{
	try
	{
		CMarkupSTL	doc;
		doc.AddElem( "portforward" );

		for ( PORTFORWARDLIST::const_iterator iCur=lst.begin();iCur!=lst.end();iCur++ )
		{
			const PORTFORWARDRULE& rule = *iCur;

			if ( rule.bAutoRule) continue;

			doc.AddChildElem( XML_TAG_ENTRY  );
			doc.AddChildAttrib( XML_ATTR_NAME,   (const char*) rule.strLabel.ToAscii() );
			doc.AddChildAttrib( XML_ATTR_PROTO,  (long) rule.proto );
			doc.AddChildAttrib( XML_ATTR_IP,	 (const char*) rule.strDst.ToAscii() );
			doc.AddChildAttrib( XML_ATTR_FROM,		rule.wPortFrom );
			doc.AddChildAttrib( XML_ATTR_FROM_TO,	rule.wPortFromTo );
			doc.AddChildAttrib( XML_ATTR_TO,		rule.wPortTo );
			doc.AddChildAttrib( XML_ATTR_ENABLED,	rule.bEnabled?XML_VAL_TRUE:XML_VAL_FALSE);
		}

		const char* szDoc = doc.GetDoc().c_str();

		//save here
		m_cfgStorage.SetPortForwardXML( wxString::FromAscii( szDoc ) );
	}
	catch(...)
	{
	}
}

//Update check
bool CPropertyStorage::GetUpdCheck()
{
	return GetBoolProperty( XML_ATTR_UPD_CHECK, true );
}

void CPropertyStorage::SetUpdCheck(bool bCheck)
{
	SetBoolProperty( XML_ATTR_UPD_CHECK, bCheck);
}

std::string	CPropertyStorage::GetScheduler()
{
	return GetStringPropertyAscii( XML_ATTR_REBOOT_SC );
}

void CPropertyStorage::SetScheduler(const std::string& str )
{
	SetStringPropertyAscii( XML_ATTR_REBOOT_SC, str );
}

bool CPropertyStorage::GetSchedulerEnabled()
{
	return GetBoolProperty( XML_ATTR_REBOOT_SC_ENBL, false );
}

void CPropertyStorage::SetSchedulerEnabled(bool bSet)
{
	SetBoolProperty( XML_ATTR_REBOOT_SC_ENBL, bSet );
}

///////////////////////////////////////////////////////////////
//Log
void CPropertyStorage::SetEnableAppLogSave( bool bSet )
{
	SetBoolProperty( XML_ATTR_APPLOG_SAVE_ENBL, bSet );
}

bool CPropertyStorage::GetEnableAppLogSave()
{
	return GetBoolProperty( XML_ATTR_APPLOG_SAVE_ENBL, false );
}

void CPropertyStorage::SetAppLogSaveFileName( const wxString& str )
{
	SetStringProperty( XML_ATTR_APPLOG_FN, str );
}

wxString CPropertyStorage::GetAppLogSaveFileName()
{
	return GetStringProperty( XML_ATTR_APPLOG_FN );
}

void CPropertyStorage::SetAppLogSaveLimit( long lLimit )
{
	SetLongProperty( XML_ATTR_APPLOG_LIM, lLimit );
}

long CPropertyStorage::GetAppLogSaveLimit()
{
	return GetLongProperty( XML_ATTR_APPLOG_LIM, UNLIMITED_SIZE );
}

void CPropertyStorage::SetAppLogStatusInterval( long lLimit )
{
	SetLongProperty( XML_ATTR_APPLOG_INT, lLimit );
}

long CPropertyStorage::GetAppLogStatusInterval()
{
	return GetLongProperty( XML_ATTR_APPLOG_INT, STATUS_LOG_DISABLED );
}

void CPropertyStorage::SetEnablePerfomanceLog( bool bSet )
{
	SetBoolProperty( XML_ATTR_APPLOG_PERF_ENBL, bSet );
}

bool CPropertyStorage::GetEnablePerfomanceLog()
{
	return GetBoolProperty( XML_ATTR_APPLOG_PERF_ENBL, false );
}

void CPropertyStorage::SetEnableConnectionsLog( bool bSet )
{
	SetBoolProperty( XML_ATTR_APPLOG_CONN_ENBL, bSet );
}

bool CPropertyStorage::GetEnableConnectionsLog()
{
	return GetBoolProperty( XML_ATTR_APPLOG_CONN_ENBL, false );
}

void CPropertyStorage::SetEnableBandwidthLog( bool bSet )
{
	SetBoolProperty( XML_ATTR_APPLOG_BNDW_ENBL, bSet );
}

bool CPropertyStorage::GetEnableBandwidthLog()
{
	return GetBoolProperty( XML_ATTR_APPLOG_BNDW_ENBL, false );
}

void CPropertyStorage::SetEnableAccessLog( bool bSet )
{
	SetBoolProperty( XML_ATTR_APPLOG_ACCSS_ENBL, bSet );
}

bool CPropertyStorage::GetEnableAccessLog()
{
	return GetBoolProperty( XML_ATTR_APPLOG_ACCSS_ENBL, false );
}

void CPropertyStorage::SetEnableADSLLog( bool bSet )
{
	SetBoolProperty( XML_ATTR_APPLOG_ADSL_ENBL, bSet );
}

bool CPropertyStorage::GetEnableADSLLog()
{
	return GetBoolProperty( XML_ATTR_APPLOG_ADSL_ENBL, false );
}

bool CPropertyStorage::GetEnablePingLog()
{
	return GetBoolProperty( XML_ATTR_APPLOG_PING_ENBL, false );
}

void CPropertyStorage::SetEnablePingLog( bool bSet )
{
	SetBoolProperty( XML_ATTR_APPLOG_PING_ENBL, bSet );
}

void CPropertyStorage::SetEnableWirelessLog( bool bSet )
{
	SetBoolProperty( XML_ATTR_APPLOG_WRLSS_ENBL, bSet );
}

bool CPropertyStorage::GetEnableWirelessLog()
{
	return GetBoolProperty( XML_ATTR_APPLOG_WRLSS_ENBL, false );
}

///////////////////////////////////////////////////////////////////
//Port Forward
void CPropertyStorage::SetEnableAllowPFPolicy(bool bSet)
{
	SetBoolProperty( XML_ATTR_PF_ENABLE_ALLOW_POLICY, bSet );
}

bool CPropertyStorage::GetEnableAllowPFPolicy()
{
	return GetBoolProperty( XML_ATTR_PF_ENABLE_ALLOW_POLICY, false );
}

void CPropertyStorage::SetEnableBlockPFPolicy(bool bSet)
{
	SetBoolProperty( XML_ATTR_PF_ENABLE_BLOCK_POLICY, bSet );
}

bool CPropertyStorage::GetEnableBlockPFPolicy()
{
	return GetBoolProperty( XML_ATTR_PF_ENABLE_BLOCK_POLICY, true );
}

void CPropertyStorage::SetAllowPFPolicy(const TEXTLIST& lst )
{
	SetStringList(XML_ATTR_PF_ALLOW_POLICY, lst);
}

TEXTLIST CPropertyStorage::GetAllowPFPolicy()
{
	return GetStringList(XML_ATTR_PF_ALLOW_POLICY);
}

void CPropertyStorage::SetBlockPFPolicy(const TEXTLIST& lst )
{
	SetStringList(XML_ATTR_PF_BLOCK_POLICY, lst);
}

TEXTLIST CPropertyStorage::GetBlockPFPolicy()
{
	return GetStringList(XML_ATTR_PF_BLOCK_POLICY);
}


PINGDATALIST CPropertyStorage::LoadPingList()
{
	PINGDATALIST lst;

	try
	{
		wxString str = m_cfgStorage.GetPingXML();

		CMarkupSTL	doc;

		if ( doc.SetDoc(str.ToAscii()) )
		{
			while ( doc.FindChildElem(XML_TAG_ENTRY) )
			{
				PingData rule;

				rule.stPingFailedCnt = 0;
				rule.tLastFailed = -1;
	
				rule.strHost = wxString::FromUTF8( doc.GetChildAttrib(XML_ATTR_IP).c_str() );
				rule.stInterval = atol( doc.GetChildAttrib(XML_ATTR_INT).c_str() );
				rule.stToActionCnt  = atol( doc.GetChildAttrib(XML_ATTR_ACTION_CNT).c_str() );
				rule.action = (cPingFailedAction)atol( doc.GetChildAttrib(XML_ATTR_ACTION).c_str() );
				rule.strPathToFile =  wxString::FromUTF8( doc.GetChildAttrib(XML_ATTR_FILE).c_str() );
				rule.color = wxColor( wxString::FromUTF8(doc.GetChildAttrib(XML_ATTR_COLOR).c_str()) );
				rule.cStatus =(cPingStatus)atol( doc.GetChildAttrib(XML_ATTR_STATUS).c_str() );

				lst.push_back(rule);
			}
		}
	}
	catch(...)
	{
	}

	return lst;
}

void CPropertyStorage::SavePingList(const PINGDATALIST& lst)
{
	try
	{
		CMarkupSTL	doc;
		doc.AddElem( "ping" );

		for ( PINGDATALIST::const_iterator iCur=lst.begin();iCur!=lst.end();iCur++ )
		{
			const PingData& rule = *iCur;

			doc.AddChildElem( XML_TAG_ENTRY  );
			doc.AddChildAttrib( XML_ATTR_IP,		(const char*) rule.strHost.ToUTF8() );
			doc.AddChildAttrib( XML_ATTR_INT,		rule.stInterval );
			doc.AddChildAttrib( XML_ATTR_ACTION_CNT,rule.stToActionCnt );
			doc.AddChildAttrib( XML_ATTR_ACTION,	rule.action );
			doc.AddChildAttrib( XML_ATTR_FILE,		(const char*)rule.strPathToFile.ToUTF8() );
			doc.AddChildAttrib( XML_ATTR_COLOR,		(const char*)rule.color.GetAsString().ToUTF8() );
			doc.AddChildAttrib( XML_ATTR_STATUS,	rule.cStatus );
		}

		const char* szDoc = doc.GetDoc().c_str();

		//save here
		m_cfgStorage.SetPingXML( wxString::FromAscii( szDoc ) );
	}
	catch(...)
	{
	}
}
